<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/5/17
 * Time: 17:02
 * @todo 此task例子是基于websocket的，task可以适用http，tcp，udp
 */
class Ws
{
    const HOST = '0.0.0.0';
    const PORT = 8899;
    public $ws = null;
    public function __construct()
    {
        $this->ws = new swoole_websocket_server(self::HOST, self::PORT);
        $this->ws->set([
            'worker_num' => 3,
            'task_worker_num' => 2
        ]);

        $this->ws->on('open', [$this, 'onOpen']);
        $this->ws->on('message', [$this, 'onMessage']);
        $this->ws->on('task', [$this, 'onTask']);
        $this->ws->on('finish', [$this, 'onFinish']);
        $this->ws->on('close', [$this, 'onClose']);

        $this->ws->start();
    }

    /**
     * 监听连接事件
     * @param $ws
     * @param $request
     */
    public function onOpen($ws, $request)
    {
        echo "clinet_{$request->fd} 连接成功!" . PHP_EOL;
        if($request->fd == 1){
            //每2s打印一次
            swoole_timer_tick('2000', function($timer_id) use($request){
                echo "2s-timerId:{$timer_id}, clientId:{$request->fd}" . PHP_EOL;
            });
        }
    }

    /**
     * 监听消息事件
     * @param $ws
     * @param $frame
     */
    public function onMessage($ws, $frame)
    {
        echo "client:{$frame->fd}-push-message:{$frame->data}" . PHP_EOL;
        //todo 10s
        $data = [
            'task'=> 1,
            'fd' => $frame->fd
        ];
        //$ws->task($data);
        swoole_timer_after('5000', function() use($ws, $frame){
            echo "5s-after" . PHP_EOL;
            $ws->push($frame->fd, 'servce-time-after:' . date("Y-m-d H:i:s"));
        });
        $ws->push($frame->fd, "server-push-time:".date("Y-m-d H:i:s"));
    }

    /**
     * 监听task事件
    */
    public function onTask($serv, $task_id, $work_id, $data)
    {
        print_r($data);
        //假设执行task任务需要耗时10s
        sleep(10);
        return 'task finish success!';
    }

    /**
     * 监听任务完成事件
     * @param $data 注意，这里的data是onTask 返回的内容
    */
    public function onFinish($serv, $task_id, $data)
    {
        echo "taskId:{$task_id}" . PHP_EOL;
        echo "finish-data-success:{$data}--" .date('Y-m-d H:i:s') . PHP_EOL;
    }

    /**
     *  监听关闭事件
     * @param $ws
     * @param $fd
     */
    public function onClose($ws, $fd)
    {
        echo "client {$fd} closed" . PHP_EOL;
    }

}

$ws = new Ws();